package xxy.com.yangproject.ui.activity;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Color;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.constraintlayout.widget.Barrier;
import androidx.constraintlayout.widget.ConstraintAttribute;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.view.LayoutInflaterCompat;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.security.crypto.EncryptedFile;
import androidx.security.crypto.MasterKeys;
import androidx.transition.TransitionManager;
import androidx.transition.Visibility;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.security.keystore.KeyGenParameterSpec;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOverlay;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.constant.PermissionConstants;
import com.blankj.utilcode.util.AdaptScreenUtils;
import com.blankj.utilcode.util.EncryptUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Observer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Interceptor;
import okhttp3.ResponseBody;
import okhttp3.internal.platform.Platform;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import xxy.com.yangproject.BaseActivity;
import xxy.com.yangproject.R;
import xxy.com.yangproject.global.Constant;
import xxy.com.yangproject.global.YangApplication;
import xxy.com.yangproject.interfaces.TestInterface;
import xxy.com.yangproject.model.LoginBean;
import xxy.com.yangproject.model.NbaBean;
import xxy.com.yangproject.network.GetRequestInterface;
import xxy.com.yangproject.network.MyObsereveListener;
import xxy.com.yangproject.network.NetWorkManager;
import xxy.com.yangproject.ui.view.Mydialog;
import xxy.com.yangproject.ui.view.ProgressUpdate;
import xxy.com.yangproject.utils.TestLrucahe;

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;


public class Main3Activity extends BaseActivity implements Observer {

    private static final String TAG = "ThreeMan";
    private static final String DIRECTORY = Environment.DIRECTORY_DOWNLOADS;
    private MediaRecorder mediaRecorder;
    private TextView tvRecord;
    private ImageView imageView;
    private Map<String, String> hashMap = Collections.synchronizedMap(new HashMap<String, String>());
    private MyObserve myObserve;
    private Mydialog mydialog;
    public final static String ACTION = "com.mytian.appstore.tv.huawei.ui.setting.AccountFragment";
    private BindPhoneBroadcast bindPhoneBroadcast;
    private Button bt_dialog;
    private Button bt_next;
    private MyViewModel myViewModel;
    private ConstraintLayout mConstraintlayout;
    private ConstraintSet constraintSetReset;
    private Map<String, Integer> stringIntegerMap = Collections.synchronizedMap(new HashMap<String, Integer>());
    private RecyclerView recyclerView;
    private static Thread thread;
    private static int count;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        AdaptScreenUtils.adaptWidth(getResources(), 240);
        bt_dialog = (Button) findViewById(R.id.button_dialog);
        bt_next = (Button) findViewById(R.id.bt_next);
        mConstraintlayout = (ConstraintLayout) findViewById(R.id.constraintlayout_main3);
        recyclerView = findViewById(R.id.recyclerView);
        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.clone(mConstraintlayout);
        constraintSetReset = new ConstraintSet();
        constraintSetReset.clone(mConstraintlayout);
        TransitionManager.beginDelayedTransition(mConstraintlayout);
        findViewById(R.id.bt_next).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Main3Activity.this, Main4Activity.class));
                if (myViewModel != null) {
                    myViewModel.getMutableLiveData().setValue("viewmodel success!");
                }
            }
        });
        findViewById(R.id.button_dialog).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //柔记
                Intent intent = new Intent();
                intent.setAction("android.intent.action.VIEW");
                Uri content_url = Uri.parse("http://app.hicloud.com/app/C100153097");
                intent.setData(content_url);
                startActivity(intent);
                overridePendingTransition(0, 0);

                mydialog = new Mydialog(Main3Activity.this, R.style.TestDialog);
                mydialog.show();
                mydialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @java.lang.Override
                    public void onDismiss(DialogInterface dialog) {
                        constraintSetReset.applyTo(mConstraintlayout);        //还原初始的Constraintlayout布局
                        bt_dialog.setBackgroundColor(getResources().getColor(R.color.text_error));
                    }
                });
                constraintSet.constrainPercentWidth(R.id.button_dialog, 1f);
                constraintSet.setColorValue(R.id.button_dialog, "color", R.color.colorAccent);
                ConstraintSet.PropertySet propertySet = new ConstraintSet.PropertySet();
                bt_dialog.setBackgroundColor(getResources().getColor(R.color.colorAccent));
                constraintSet.applyTo(mConstraintlayout);
            }
        });
        //进度条
//        init0();
        //jsonobject
//        init5();
        //observable
//        init7();
        //handler
//        init8();
        //service
//        init9();
        //workmanager
//        init10();
        //ViewModel livedata
//        init11();
        //集合
//        init12();
        //测试回调监听
//        init13();
        //重命名文件
//        init14();
        //display
//        init15();
        //kotlin
//        init16();
        //
//        init17();
        //write somthing
//        init18();
        //AIDL
//        init19();
        //recyclerview滑动
//        init20();
        //线程latch.countDown
//        init21();
        //反射
//        init22();
        //轮循操作
//        init23();
        //多线程
        init24();
        //以下代码段演示了如何使用 EncryptedFile 以更安全的方式读取文件内容：
//        init25();
    }

    public static void init26(){
        count = 0;
        thread = new Thread(new Runnable() {
            @java.lang.Override
            public void run() {   //开启子线程调用Object.class.wait()
                while (count <= 100){
                    synchronized (Object.class){
                        try {
                            LogUtils.eTag("thread", " Object.class.wait()");
                            Object.class.wait();
                            LogUtils.eTag("thread", " 计算结果 count = " + count ++ );   //加一跳出while循环
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread.start();

        new Thread(new Runnable() {
            @java.lang.Override
            public void run() {
                synchronized (Object.class){
                    while (count < 100){
                        count++;
                    }
                    LogUtils.eTag("thread", " Object.class.notify()");
                    Object.class.notify();
                }
            }
        }).start();
    }

    private static int i = 0;

    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    private static Runnable testRunnable = new Runnable() {
        @java.lang.Override
        public void run() {
//            synchronized (this){
//                for (int j = 0; j < 100; j++) {
//                    i++;
//                }
//            }

            //线程t1执行完代码块后释放了锁，线程t2可以得到，然后执行
            synchronized (lock1){
                System.out.println("我是对象锁的代码块形式，我叫"+ Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("我是对象锁的代码块形式，我叫"+ Thread.currentThread().getName()+"运行结束");
            }

            //线程t1释放完lock1锁后，得到lock2锁，执行此代码块
            synchronized (lock2){
                System.out.println("我是对象锁的代码块形式第2个，我叫"+ Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("我是对象锁的代码块形式第2个，我叫"+ Thread.currentThread().getName()+"运行结束");
            }
        }
    };
    public static void main(String[] args){
//        init24();
        //4、以原子方式设置为给定值，并返回旧值，先获取当前对象，在设置新的对象
//        NbaBean test1 = new NbaBean("Kobe" , "50");
//        AtomicReference<NbaBean> atomicReference3 = new AtomicReference<>(test1);
//        NbaBean simpleObject2 = atomicReference3.getAndSet(new NbaBean("Jordan","40"));
//        NbaBean simpleObject3 = atomicReference3.get();
//        System.out.println("simpleObject  Value: " + simpleObject2.toString());
//        System.out.println("simpleObject  Value: " + simpleObject3.toString());
    }

    private static void init24() {
        //wait,如果在主线程调用object.wait(),会导致主线程阻塞，消息栈无法轮循，ui消息一直等待
        init26();
        //join
//        init27();
    }

    private static void init27(){
        try {
            // 开启两个线程 公用同一个instance实例
            Thread t1 = new Thread(testRunnable);
            Thread t2 = new Thread(testRunnable);
            t1.start();
            t2.start();
            // 让线程先等待一会 先输出i
            t1.join();
            t2.join();
            System.out.println(i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static final String TAG_23 = "init23";
    Handler handler = new Handler(Looper.getMainLooper());
    //轮循操作
    private void init23() {
//        Uri parse = Uri.parse("https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2270291680,4103254225&fm=26&gp=0.jpg");
//        String queryParameter = parse.getQueryParameter("u");
//        LogUtils.eTag(TAG_23, "parse.getQueryParameter 的值 :" + queryParameter + "\n" + "parse.getScheme  的值 : " + parse.getScheme()
//                + "\n" + "parse.getQueryParameter(\"gp\")" + parse.getQueryParameter("gp")
//                + "\n" + "Uri.decode(parse.getQueryParameter(\"gp\"))) : " + Uri.decode(parse.getQueryParameter("gp")));
//        //handler做轮循操作
//        final int[] i = {0};
//        Runnable runnable = new Runnable() {
//            @java.lang.Override
//            public void run() {
//                if (i[0]++ == 10) {
//                    return;
//                }
//                LogUtils.eTag("loop", i[0] + "");
//                handler.postDelayed(this, 100);
//            }
//        };
//
//        //Timer做轮循操作
//        Timer timer = new Timer();
//        TimerTask timerTask = new TimerTask() {
//            @java.lang.Override
//            public void run() {
//                if (System.currentTimeMillis() - scheduledExecutionTime() >= 1){
//                    LogUtils.eTag(TAG_23, "timerTask");
//                }
//                for (int i = 0; i < 20; i++) {
//                    LogUtils.eTag(TAG_23, i + "  scheduledExecutionTime() : " + scheduledExecutionTime() + "\n" + "" + "System.currentTimeMillis() : " +  System.currentTimeMillis() + "\n" + "(System.currentTimeMillis() - scheduledExecutionTime()) : " +(System.currentTimeMillis() - scheduledExecutionTime()));
//                    if (i == 19) {
//                        timer.cancel();
//                    }
//                }
//            }
//        };
//        timer.schedule(timerTask, 500, 500);

        //单线程池做轮循操作
        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @java.lang.Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    LogUtils.eTag(TAG_23, i + "  Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate()");
                    if (i == 19) {
                        scheduledExecutorService.shutdown();
                    }
                }
            }
        }, 500, 500, TimeUnit.MILLISECONDS);
    }

    @java.lang.Override
    protected void onResume() {
        super.onResume();
    }

    //反射
    private void init22() {
        try {
//            Class<?> bClass = getClassLoader().loadClass("xxy.com.yangproject.ui.activity.Main3Activity");
//            for (int i = 0; i < aClass.getDeclaredFields().length; i++) {
//                LogUtils.eTag("myclass", "Field : " + aClass.getDeclaredFields()[i]);
//            }
            Main3Activity.class.newInstance();
            Class<?> bClass = Class.forName("xxy.com.yangproject.ui.activity.Main3Activity");
            Main3Activity object = (Main3Activity) bClass.newInstance();
            LogUtils.eTag("myclass", "bClass.getName() : " + bClass.getName());
            Field reflect = null;
            reflect = bClass.getField("reflect2");
            reflect.setAccessible(true);
            reflect.set(object, "huahuahua");
            LogUtils.eTag(tag_init9, "reflect2的值 : " + object.reflect2);   //使 bClass 实例化，用作 filed set(object, value)的第一个参数
            Main3Activity main3Activity = (Main3Activity) bClass.newInstance();
            if (main3Activity != null) {
                LogUtils.eTag(tag_init9, "main3Activity.tag_17 : " + main3Activity.tag_17);
                main3Activity.attachBaseContext(this);    //给内部 mBase 赋值， 以防 getPackageName() 为空
                LogUtils.eTag(tag_init9, "main3Activity.getPackageName : " + main3Activity.getPackageName());
            } else {
                LogUtils.eTag(tag_init9, "main3Activity == null");
            }

        } catch (Exception e) {
            LogUtils.eTag(tag_init9, "Exception");
        }
    }

    private void init21() {
        CountDownLatch latch = new CountDownLatch(2);
        LogUtils.eTag("init21", "主线程开始运行");
        //第一个子线程
//        ExecutorService executorService = Executors.newSingleThreadExecutor();
//        executorService.execute(new Runnable() {
//            @java.lang.Override
//            public void run() {
//                try {
//                    Thread.sleep(3000);
//                    LogUtils.eTag("init21", "子线程：" + Thread.currentThread().getName() + "执行");
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                latch.countDown();
//            }
//        });
//        executorService.shutdown();

        //第二个子线程
//        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
//        executorService2.execute(new Runnable() {
//            @java.lang.Override
//            public void run() {
//                try {
//                    Thread.sleep(3000);
//                    LogUtils.eTag("init21", "子线程：" + Thread.currentThread().getName() + "执行");
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                latch.countDown();
//            }
//        });
//        executorService2.shutdown();
//        LogUtils.eTag("init21", "等待两个线程执行完毕…… ……");
//        try {
//            latch.await();      //一直等待直到latch设置的线程数量为0，才继续进行下去
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        LogUtils.eTag("init21", "两个子线程都执行完毕，继续执行主线程");
//
//        //高并发测试
//        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//        CountDownLatch countDownLatch = new CountDownLatch(100);
//        for (int i = 0; i < 100; i++) {    //100条多线程
//            TestRunnable testRunnable = new TestRunnable(countDownLatch);
//            newCachedThreadPool.execute(testRunnable);
//        }

//        for (int i = 0; i < 2; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    try {
//                        Thread.sleep(10);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    //每个线程让count自增100次
//                    for (int i = 0; i < 100; i++) {
//                        /**如果小于200，则是某个线程拿到了未经过++计算的count值 ，应该等count ++ 之后才能使用，所以要加上 synchronized (ThreadCas.class)
//                         * 也可以使用 AtomicInteger atomicInteger = new AtomicInteger(0);
//                         *           atomicInteger.incrementAndGet();
//                         */
//                        count++;
//                    }
//                }
//            }).start();
//        }
//
//        try{
//            Thread.sleep(2000);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        LogUtils.eTag("init21", "count ：" + count);

        //测试AtomicBoolean
//        AtomicRunnable atomicRunnable = new AtomicRunnable();
//        Thread thread = new Thread(atomicRunnable);
//        Thread thread2 = new Thread(atomicRunnable);
//        thread.start();
//        thread2.start();


        final CountDownLatch latch2 = new CountDownLatch(1);
        LogUtils.eTag("init21", "latch数量0 ： " + latch2.getCount());
        /**
         * 这里不能用view.post去做 latch2.countDown()，因为post是在用户界面线程也就是主线程里做操作，而latch2.await()会堵塞主线程直到latch为0才会继续进行。如果latch在post之前堵塞，那么post便不会走，latch.countdown不减一，主线程就一直会被堵塞下去，页面就一直空白
         */
        new Thread(() -> {
            latch2.countDown();
            LogUtils.eTag("init21", "latch数量1 ： " + latch2.getCount());
        }).start();

        //在onresume中执行此方法，post会执行，logutils.etag没有问题
        try {
//            latch2.countDown();
            LogUtils.eTag("init21", "latch数量2 ： " + latch2.getCount());
            latch2.await();
            LogUtils.eTag("init21", "----------------===============sdddddddddddddddddddddddddddddddddddffffffffffffffffff");
            ToastUtils.showShort("latch2.await()");
        } catch (InterruptedException e) {
            LogUtils.eTag("init21", "错误： " + e.toString());
        }

    }

    static AtomicBoolean flag = new AtomicBoolean(true);

    private static class AtomicRunnable implements Runnable {

        @java.lang.Override
        public void run() {
            LogUtils.eTag("init21", "thread:" + Thread.currentThread().getName() + ";flag:" + flag.get());
            if (flag.compareAndSet(true, false)) {   //一个线程先进行判断，true变为false，然后睡眠5秒。这时另一个线程拿到的flage是false，就一直走else方法。直到5秒睡完，flag设为true，循环就终止。
                LogUtils.eTag("init21", Thread.currentThread().getName() + "" + flag.get());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                flag.set(true);
            } else {
                LogUtils.eTag("init21", "重试机制thread:" + Thread.currentThread().getName() + ";flag:" + flag.get());
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                run();
            }
        }
    }

    //CountDownLatch用到的线程
    private static class TestRunnable implements Runnable {

        private final CountDownLatch countDownLatch;

        public TestRunnable(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @java.lang.Override
        public void run() {
            try {
                //判断？
                synchronized (countDownLatch) {
                    countDownLatch.countDown();
                    LogUtils.eTag("init21", "thread counts = " + (countDownLatch.getCount()));
                }
                countDownLatch.await();
                LogUtils.eTag("init21", "concurrency counts = " + (100 - countDownLatch.getCount()));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    private void init25(){
        Context context = getApplicationContext();

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
        KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
        String mainKeyAlias = null;
        try {
            mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);
            String fileToRead = "my_sensitive_data.txt";
            EncryptedFile encryptedFile = new EncryptedFile.Builder(
                    new File(DIRECTORY, fileToRead),
                    context,
                    mainKeyAlias,
                    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
            ).build();

            InputStream inputStream = encryptedFile.openFileInput();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int nextByte = inputStream.read();
            while (nextByte != -1) {
                byteArrayOutputStream.write(nextByte);
                nextByte = inputStream.read();
            }

            byte[] plaintext = byteArrayOutputStream.toByteArray();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //以下代码段演示了如何使用 EncryptedFile 以更安全的方式写入文件内容：
        try {
            context = getApplicationContext();

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
            keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
            mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);

// Create a file with this name, or replace an entire existing file
// that has the same name. Note that you cannot append to an existing file,
// and the file name cannot contain path separators.
            String fileToWrite = "my_sensitive_data.txt";
            EncryptedFile encryptedFile = new EncryptedFile.Builder(
                    new File(DIRECTORY, fileToWrite),
                    context,
                    mainKeyAlias,
                    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
            ).build();

            byte[] fileContent = "MY SUPER-SECRET INFORMATION"
                    .getBytes(StandardCharsets.UTF_8);
            OutputStream outputStream = null;
            outputStream = encryptedFile.openFileOutput();
            outputStream.write(fileContent);
            outputStream.flush();
            outputStream.close();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void init20() {
        recyclerView.setLayoutManager(new LinearLayoutManager(this,
                LinearLayoutManager.HORIZONTAL, false));

        RecyclerView.Adapter adapter = new RecyclerView.Adapter() {

            @NonNull
            @java.lang.Override
            public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                final AppCompatImageView pageItem = new AppCompatImageView(parent.getContext());
                pageItem.setBackgroundColor(Color.WHITE);
                pageItem.setLayoutParams(new FrameLayout.LayoutParams(parent.getWidth(),
                        parent.getHeight()));
                return new RecyclerView.ViewHolder(pageItem) {
                    @java.lang.Override
                    public String toString() {
                        return super.toString();
                    }
                };
            }

            @java.lang.Override
            public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
//                ((AppCompatImageView) (holder.itemView)).setImageResource(0 == position ?
//                        R.drawable.guide_page_01 : 1 == position ? R.drawable.guide_page_02 :
//                        R.drawable.guide_page_03);
                ToastUtils.showShort(position);
                ((AppCompatImageView) (holder.itemView)).setImageResource(R.drawable.backgroud);
            }

            @java.lang.Override
            public int getItemCount() {
                return 3;
            }
        };
        recyclerView.setAdapter(adapter);
        PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
        pagerSnapHelper.attachToRecyclerView(recyclerView);
    }

    private void init19() {
        TestInterface2 kobe = new TestInterface2("kobe");
        //代理：帮你完成某些事情
        TestInterface testInterface = (TestInterface) Proxy.newProxyInstance(kobe.getClass().getClassLoader(), kobe.getClass().getInterfaces(), new InvocationHandler() {
            @java.lang.Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getName().equals("testMethod")) {
                    method.invoke(kobe, 2);
                }
                return null;
            }
        });
    }

    private class TestInterface2 implements TestInterface {
        public String name;

        public TestInterface2(String name) {
            this.name = name;
        }

        @java.lang.Override
        public void testMethod() {
            LogUtils.eTag(Constant.AIDL_TEST, name + " is coding.");
        }

    }

    private void init18() {

        registerReceiver(bindPhoneBroadcast = new BindPhoneBroadcast(), new IntentFilter(ACTION));
        new Thread(new Runnable() {
            @java.lang.Override
            public void run() {
                bt_dialog.setText("子线程");
            }
        }).start();

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @java.lang.Override
            public void run() {
                bt_next.setText("next page");
            }
        });

        NetWorkManager.getInstance().getRequestInterface.test("test").subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new MyObsereveListener<LoginBean>() {
                    @java.lang.Override
                    public void onResponse(LoginBean loginBean) {
                        ToastUtils.showShort(loginBean.description);
                        if (loginBean.result == Constant.SUCCESS) {
                            ToastUtils.showShort("请求成功!");
                        }
                    }
                });
        myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
        myViewModel.getMutableLiveData().observe(this, new androidx.lifecycle.Observer<String>() {
            @java.lang.Override
            public void onChanged(String s) {
                ToastUtils.showLong(s);
            }
        });

        //
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.writeValueAsString("xxx");
            BufferedSink buffer = Okio.buffer(new GzipSink(Okio.sink(new File(YangApplication.applictionContext.getExternalCacheDir(), "buffer")))).write(new byte[1024]);
            buffer.flush();
        } catch (Exception e) {
            LogUtils.eTag(Constant.TAG, e.toString());
        }


    }

    public static class MyViewModel extends ViewModel {

        MutableLiveData<String> mutableLiveData = new MutableLiveData<>();

        public MyViewModel(MutableLiveData<String> mutableLiveData) {
            this.mutableLiveData = mutableLiveData;
        }

        public MyViewModel() {

        }

        public MutableLiveData<String> getMutableLiveData() {
            return mutableLiveData;
        }
    }

    //绑定完手机号后，通知账号页面展示手机号
    private class BindPhoneBroadcast extends BroadcastReceiver {

        @java.lang.Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() != null && intent.getAction().equals(ACTION)) {
                ((Button) findViewById(R.id.button_dialog)).setText("接收到广播");
            }
        }
    }

    String tag_17 = "intent";

    private void init17() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setAction(Intent.ACTION_SEARCH);
        intent.addCategory(Constant.CATEGORY);
        List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(intent, 0);
        LogUtils.eTag(tag_17, "resolveInfos.size() : " + resolveInfos.size());
        for (int i = 0; i < resolveInfos.size(); i++) {
            ResolveInfo resolveInfo = resolveInfos.get(i);
            LogUtils.eTag(tag_17, "packageName : " + resolveInfo.activityInfo.packageName);
            if (!getPackageName().equalsIgnoreCase(resolveInfo.activityInfo.packageName)) {   //可能有其他包的匹配上，所以添加判断
                continue;
            }
            String s = resolveInfo.loadLabel(getPackageManager()).toString();     //项目名称
            LogUtils.eTag(tag_17, "resolveInfo.loadLabel(getPackageManager()) : " + s);

        }
        int a = 0;
        {
            int b = 1;
            a = a + b;
            LogUtils.eTag(Constant.TAG, "第一个代码块" + "\n" + "a的值  :  " + a);
        }

        {
            int b = 1;
            a = a + b;
            LogUtils.eTag(Constant.TAG, "第二个代码块" + "\n" + "a的值  :  " + a);
        }

        {
            int b = 1;
            a = a + b;
            LogUtils.eTag(Constant.TAG, "第三个代码块" + "\n" + "a的值  :  " + a);
        }

    }


    /**
     * 注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释
     */
    @Target({FIELD, CONSTRUCTOR})
    @Retention(RetentionPolicy.CLASS)
    public @interface Haha {
        int a = 1;

        String test();

        int test2();
    }

    @Haha(test = "", test2 = 1)
    @SuppressWarnings({"unchecked"})
    private String test;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {

    }

    class A {
        void c() {

        }
    }

    class B extends A {
        @Override
        void c() {
            super.c();
        }

        @java.lang.Override
        public int hashCode() {
            return super.hashCode();
        }
    }

    /**
     * 注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释注释
     */


    @Override
    private void init16() {
        WindowManager windowManager = getWindowManager();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        int widthPixels = displayMetrics.widthPixels;
        int heightPixels = displayMetrics.heightPixels;
    }

    private void init15() {
        //保持布局状态
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                //布局位于状态栏下方
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                //全屏
                View.SYSTEM_UI_FLAG_FULLSCREEN |
                //隐藏导航栏
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        if (Build.VERSION.SDK_INT > 22) {
            uiOptions |= 0x00001000;
        } else {
            uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
        }
        getWindow().getDecorView().setSystemUiVisibility(uiOptions);

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        LogUtils.eTag(Constant.TAG, "getWindowManager().getDefaultDisplay().getMetrics(displayMetrics)方法得来的宽和高 ： " + displayMetrics.widthPixels + "\t" + displayMetrics.heightPixels);  //result : 1920  1080
        DisplayMetrics displayMetrics1 = getResources().getDisplayMetrics();
        LogUtils.eTag(Constant.TAG, "getResources().getDisplayMetrics()方法得来的宽和高 ： " + displayMetrics1.widthPixels + "\t" + displayMetrics1.heightPixels);    //result : 1920  1080

    }

    //重命名文件
    private void init14() {
        File file = new File(getExternalCacheDir(), "a");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        File file1 = new File(file.getParent(), "b");
        if (file.renameTo(file1)) {
            LogUtils.eTag("yang", "重命名成功");
        }
    }

    @Override
    public void update(java.util.Observable o, Object arg) {
        LogUtils.eTag("yang", "update收到");
    }

    protected static class MyObserve extends java.util.Observable {

        private void notifyA() {
            setChanged();
            notifyObservers(0);
        }
    }

    private void init13() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
//                while (true){
//                    LogUtils.eTag("yang", "线程运行中");
//                }
                LogUtils.eTag("yang", "线程运行中");
            }
        });
        thread.setPriority(Thread.NORM_PRIORITY);
        thread.setDaemon(true);
        thread.start();

        myObserve = new MyObserve();
        myObserve.addObserver(this);
        myObserve.notifyA();
    }

    //集合
    private void init12() {
    }

    //ViewModel livedata
    private void init11() {
        //实体类根据业务需求可分为以下几种关系：
        //一对一 一对多 多对多
        //roomdatabase entity
    }

    //workmanager
    private void init10() {
//        WorkManager workManager = WorkManager.getInstance(this);
//        workManager.enqueue(new OneTimeWorkRequest.Builder(MyWork.class).build());
//        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
//        intent.setType("application/pdf");
//        intent.addCategory(Intent.CATEGORY_OPENABLE);
//        intent.putExtra(Intent.EXTRA_TITLE, "threeMan.pdf");
//        // Optionally, specify a URI for the directory that should be opened in
//        // the system file picker when your app creates the document.
//        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, "content://xxy.com.yangproject/file/");
//
//        startActivityForResult(intent, 1);
//
//        SharedPreferences a = getSharedPreferences("a", MODE_PRIVATE);
//        SharedPreferences.Editor edit = a.edit();
//        edit.putInt(Constant.Version, 100);
//        edit.apply();
//        CursorLoader cursorLoader = new CursorLoader(this);
//        cursorLoader.loadInBackground();
//        Cursor cursor = getContentResolver().query(UserDictionary.Words.CONTENT_URI, new String[]{"1", "2"}, "", new String[]{}, "");
//        while (cursor.moveToNext()){
//            int columnIndexOrThrow = cursor.getColumnIndexOrThrow("1");
//            getContentResolver().query(UserDictionary.Words.CONTENT_URI, new String[]{"_ID"}, "where name is ?", new String[]{"4"}, null);
//        }
//        String breakSql = "name = ?";
//        String querySql = "var= " + breakSql;
//        System.out.println();
//        String[] argSql = new String[]{"4", "5"};
//        ParcelFileDescriptor r = null;
//        try {
//            r = getContentResolver().openFileDescriptor(UserDictionary.Words.CONTENT_URI, "r");
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//        FileDescriptor fileDescriptor = r.getFileDescriptor();
//        ContentValues contentValues = new ContentValues();
//        contentValues.put(UserDictionary.Words.WORD, "Iverson");
//        contentValues.put(UserDictionary.Words.LOCALE, "America");
//        getContentResolver().insert(UserDictionary.Words.CONTENT_URI, contentValues);
//        long parseId = ContentUris.parseId(UserDictionary.Words.CONTENT_URI);
//        String updateLocale = UserDictionary.Words.CONTENT_URI + "LIKE ?";
//        String[] updateArgs = new String[]{"en%"};
//        contentValues.putNull(UserDictionary.Words.LOCALE);
//        int update = getContentResolver().update(UserDictionary.Words.CONTENT_URI, contentValues, updateLocale, updateArgs);
//        ArrayMap<Object, Object> objectObjectArrayMap = new ArrayMap<>();
//        String s = BaseColumns._ID;
//        UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//        uriMatcher.addURI("user_dictionary", "words", 1);
//        switch (uriMatcher.match(Uri.parse("user_dictionarywords"))){
//            case 1:
//                //todo
//                ToastUtils.showShort("this id is 1");
//                break;
//        }
//        Bundle bundle = new Bundle();
//        bundle.putString("1", "2");
//        LoaderManager.getInstance(this).initLoader(1, bundle, new VideoLoaderCallbacks());
    }

    protected class VideoLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {

        @NonNull
        @Override
        public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
            return null;
        }

        @Override
        public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {

        }

        @Override
        public void onLoaderReset(@NonNull Loader<Cursor> loader) {

        }
    }

    /**
     * workmanager里的最小工作单元
     */
//    public static class MyWork extends Worker {
//
//        public MyWork( Context context,  WorkerParameters workerParams) {
//            super(context, workerParams);
//        }
//
//
//        @NotNull
//        @Override
//        public Result doWork() {
//            //todo
//
//            return Result.success();
//        }
//    }

    public String reflect2 = "reflect";
    public String tag_init9 = "myclass";

    //service
    private void init9() {
        //隐式启动需要加上包名
        Intent intent = new Intent(getPackageName() + ".service");
        intent.putExtra(Constant.INTENT_TEST, "开启service");
        //隐式intent开启服务，为了安全问题，设置包名后，就只在本应用内打开，而不会和其他应用有操作
        intent.setPackage(getPackageName());
//        Intent intent1 = new Intent(this, TestService.class);   //显示，指定名称
        LogUtils.eTag(Constant.TAG, "类名 : " + this.getClass().getName() + "\t线程ID ： " + Thread.currentThread().getId());
        startService(intent);
    }

    private void init8() {
        HandlerThread handlerThread = new HandlerThread(TAG);
        handlerThread.start();
        Handler handler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                if ((int) msg.what == 1) {
                    ToastUtils.showShort("1");
                }
                return false;
            }
        });

        handler.sendEmptyMessageDelayed(1, 1000);
    }


    //进度条
    private void init0() {
        final ProgressUpdate progressbar = findViewById(R.id.update_progressbar);
        final int[] progress = {0};
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                progressbar.setProgress(progress[0]);
                progress[0] += 10;
            }
        }, 0, 500);
    }

    //rxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjava
    private void init7() {
        Observable<String> stringObservable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.serialize().onNext("1");
                emitter.serialize().onNext("2");
                emitter.serialize().onNext("3");
                emitter.serialize().onComplete();
            }
        });

        String[] stringList = {"1", "2", "3"};
        Disposable subscribe = Observable.fromArray(stringList)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        LogUtils.eTag(TAG, s);
                    }
                });

        Disposable subscribe1 = Observable.just("1123213")
                .map(new Function<String, Long>() {
                    @Override
                    public Long apply(String s) throws Exception {
                        return Long.valueOf(s) * 100000;
                    }
                })
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long l) throws Exception {
                        LogUtils.eTag(TAG, l);
                    }
                });

//        Disposable subscribe2 = Observable.just(111)
//                .map(new TestFunction<Integer, String>())
//                .observeOn(Schedulers.io())
//                .subscribeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<String>() {
//                    @java.lang.Override
//                    public void accept(String s) throws Exception {
//                        ToastUtils.showShort(s);
//                    }
//                });

        Disposable subscribe2 = Observable.just("Iverson!")
                .observeOn(Schedulers.io())
                .map(new Function<String, ArrayList<String>>() {
                    @java.lang.Override
                    public ArrayList<String> apply(String s) throws Exception {
                        ArrayList<String> stringArrayList = new ArrayList<>();
                        stringArrayList.add("Answer: " + s);
                        return stringArrayList;
                    }
                })
                .observeOn(Schedulers.io())
                .map(new Function<ArrayList<String>, String>() {

                    @java.lang.Override
                    public String apply(ArrayList<String> strings) throws Exception {
                        for (String string : strings) {

                            return string + " I like him.";
                        }
                        return "null";
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @java.lang.Override
                    public void accept(String s) throws Exception {
                        LogUtils.eTag(TAG, s);
                        ToastUtils.showShort(s);
                    }
                });

        ;
    }
    //rxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjavarxjava

    public class TestFunction<T extends Integer, P extends String> implements Function<T, P> {

        @java.lang.Override
        public P apply(T t) throws Exception {
            return null;
        }
    }

    //泛型
    private void init6() {
        ArrayList<String> stringArrayList = new Fanxing<String>().add("1");
        Iterator<String> iterator = stringArrayList.iterator();

    }

    private static class Fanxing<T> {

        private final ArrayList<T> arrayList;

        public Fanxing() {
            arrayList = new ArrayList<T>();
        }

        ArrayList<T> add(T t) {
            arrayList.add(t);
            return arrayList;
        }
    }

    //json
    private void init5() {
        String data = "{\"action\":\"recordAlive\",\"args\":{\"param\":{\"sampleRate\":16000}}}";

        JSONObject jsonObject2 = JSONObject.parseObject(data);
        JSONObject args = jsonObject2.getJSONObject("args");
        JSONObject param1 = args.getJSONObject("param");
        String sampleRate1 = param1.getString("sampleRate");
        LogUtils.eTag(TAG, "args对应的值 ： " + "\n " + args.toString() + "\n " + "sampleRate 的值 ： " + sampleRate1);
    }

    //录音
    private void init4() {
        Button btStart = findViewById(R.id.bt_start);
        Button btStop = findViewById(R.id.bt_stop);
        tvRecord = findViewById(R.id.tv_record);
        webview();

        btStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                requirePermission(0);
            }
        });

        btStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                requirePermission(1);
            }
        });
    }

    private void webview() {
        BridgeWebView webView = new BridgeWebView(this);
        webView.loadUrl("file:///android_asset/Ha.html");
        webView.registerHandler("HaHa", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                function.onCallBack("已经接收到数据" + data);
            }
        });
    }

    //加密
    private void init3() {
        String s = EncryptUtils.encryptMD5ToString("49513c1385ba8dd1a7c1b949188f358e");
        LogUtils.eTag(TAG, s);

    }

    private void init2() {
        String json = "{\"description\":\"登陆成功！\",\"result\":1,\"systemTime\":1591680672484,\"info\":{\"uid\":110805813,\"userInfo\":{\"id\":11033409,\"uid\":110805813,\"token\":\"26a18e1c-4c85-4f4a-9582-c565912e784b\",\"alias\":null,\"password\":null,\"sex\":null,\"phone\":\"13564315424\",\"birthday\":null,\"createTime\":1589852850317,\"updateTime\":1590976273000,\"status\":1,\"headThumb\":null,\"email\":null,\"obj1\":\"1.0.0\",\"obj2\":\"xiaomi\",\"obj3\":\"xiaomi\",\"obj4\":\"1231111111131\",\"obj5\":null,\"obj6\":\"com.mytian.appstore.tv\",\"obj7\":\"上海\",\"thirdPath\":null,\"openId\":null},\"needComplementInfo\":1,\"phone\":\"13564315424\",\"token\":\"26a18e1c-4c85-4f4a-9582-c565912e784b\"}}";
        LoginBean loginBean = new Gson().fromJson(json, LoginBean.class);
        ToastUtils.showShort(loginBean.getDescription());
    }

    private void init1() {
        imageView = findViewById(R.id.imageView);

        Retrofit build = new Retrofit.Builder().baseUrl("https://cloud.mymaitian.com:7776/").build();
        GetRequestInterface getRequestInterface = build.create(GetRequestInterface.class);
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("phone", "15021614152");
        hashMap.put("verificationCode", "9880");
        hashMap.put("appNames", "com.mytian.appstore.tv");
        hashMap.put("channels", "xiaomi");
        Call<ResponseBody> requestBodyCall = getRequestInterface.login(hashMap);
        requestBodyCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                //将网络请求返回的数据解析为图片并展示到界面
                ResponseBody body = response.body();
                LoginBean loginBean = null;
                try {
                    loginBean = new Gson().fromJson(body.string(), LoginBean.class);
                    ToastUtils.showShort(loginBean.getDescription());
                    Log.e(TAG, "网络请求成功 : " + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG, "网络请求失敗 : " + t.toString());
            }
        });
    }

    private void startRecord() {

        File myTian = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), "record");
        if (!myTian.exists()) {
            myTian.mkdirs();
        }
        File soundFile = new File(myTian, System.currentTimeMillis() + ".mp3");
        if (!soundFile.exists()) {
            try {
                soundFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (mediaRecorder == null) {
            mediaRecorder = new MediaRecorder();
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
        }

        mediaRecorder.setOutputFile(soundFile.getAbsolutePath());

        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
            tvRecord.setText("录音文件存储在 : " + soundFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    private void stopRecord() {
        if (mediaRecorder != null) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    private void requirePermission(final int flag) {
        PermissionUtils.permission(PermissionConstants.STORAGE, PermissionConstants.MICROPHONE).callback(new PermissionUtils.SimpleCallback() {
            @Override
            public void onGranted() {
                if (flag == 0) {
                    startRecord();
                } else if (flag == 1) {
                    stopRecord();
                }
            }

            @Override
            public void onDenied() {
                ToastUtils.showLong("请去设置里打开权限");
            }
        }).request();
    }

    long pressTime = 0;

    @Override
    public void onBackPressed() {
        if ((System.currentTimeMillis() - pressTime) <= 2000) {
            super.onBackPressed();
        } else {
            ToastUtils.showShort("再按一次退出应用");
            pressTime = System.currentTimeMillis();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myObserve != null) {
            myObserve.deleteObserver(this);
        }
    }
}
